#include "filetransferitem.h"
#include "ui_filetransferitem.h"
#include "../Core/SimpleLogger.h"
#include "../Biz/FileTransfer/BaseFileTransfer.h"
#include "../Biz/FileTransfer/p2pbase.h"
#include "../Biz/WWCommonUtility.h"

#include <QFileDialog>
#include <QUrl>
#include <QDesktopServices>
using namespace core;
using namespace wwcommon;

static LoggerCategory g_log("FileTransferItem");

FileTransferItem::FileTransferItem(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::FileTransferItem),
    m_session_valid(true)
{
    ui->setupUi(this);

    QObject::connect(ui->btncancel, SIGNAL(clicked()), SLOT(OnCancel()));
    QObject::connect(ui->btnReject, SIGNAL(clicked()), SLOT(OnReject()));
    QObject::connect(ui->btnRetry, SIGNAL(clicked()), SLOT(OnRetry()));
    QObject::connect(ui->btnSave, SIGNAL(clicked()), SLOT(OnSaveFile()));
    QObject::connect(this, SIGNAL(transferProcessChanged(int)), ui->progressBar, SLOT(setValue(int)));
}

FileTransferItem::~FileTransferItem()
{
    delete ui;
}

std::string FileTransferItem::GetFileName()
{
    return m_saved_data.filename;
}
bool FileTransferItem::IsSender()
{
    return m_saved_data.issender;
}
bool FileTransferItem::IsValid()
{
    return m_session_valid;
}

void FileTransferItem::InitFileTransferData(FileTransferNotify data)
{
    m_saved_data = data;
    ui->transfer_fileName->setText(QString::fromStdString(data.filename));
    QString directstr;
    if(data.issender)
    {
        directstr = " to " + QString::fromStdString(data.destid) + ":";
        ui->btncancel->setVisible(false);
        ui->btnReject->setVisible(false);
        ui->btnSave->setVisible(false);
        ui->btnRetry->setVisible(false);
    }
    else
    {
        directstr = " from " + QString::fromStdString(data.destid) + ":";
        ui->btncancel->setVisible(false);
        ui->btnReject->setVisible(true);
        ui->btnRetry->setVisible(false);
        ui->btnSave->setVisible(true);
    }
    ui->btnOpen->setVisible(false);
    ui->transfer_DirectionLabel->setText(directstr);
    ui->transfer_eventInfo->setText("waiting...");
    m_session_valid = true;
}

void FileTransferItem::ProcessTransferNotify(FileTransferNotify fileparam)
{
    if(!m_session_valid)
        return;
    if(fileparam.notifytype == "reportevent")
    {
        ChangeTransferEvent(fileparam.notifycode);
    }
    else if(fileparam.notifytype == "reporterror")
    {
        SetTransferErrorInfo(fileparam.notifycode);
        m_session_valid = false;
        ui->btnSave->setVisible(false);
        ui->btnReject->setVisible(false);
        emit newactivity();
    }
    else if(fileparam.notifytype == "reportprocess")
    {
        ChangeTransferingProcess(fileparam.notifycode/(double)m_saved_data.filesize*100);
    }
    else
    {
        g_log.Log(lv_debug, "unknown notifytype :%s", fileparam.notifytype.c_str());
    }
}

void FileTransferItem::SetTransferErrorInfo(int errcode)
{
    switch(errcode)
    {
    case FILE_ERR_CODE_CONNECT_FAILED:
        ui->transfer_eventInfo->setText("fts server failed to connect.");
        break;
    case FILE_ERR_CODE_CONNECT_ERROR:
        ui->transfer_eventInfo->setText("connect server error.");
        break;
    case FILE_ERR_CODE_FILE_TOOLARGE:
        ui->transfer_eventInfo->setText("too large file. ");
        break;
    case FILE_ERR_CODE_INVALIDE:
        ui->transfer_eventInfo->setText("open file failed. ");
        break;
    case FILE_ERR_CODE_SIZEZERO:
        ui->transfer_eventInfo->setText("zero length not send. ");
        break;
    case FILE_ERR_CODE_NO_SPACE:
        ui->transfer_eventInfo->setText("disk space is not enough.");
        break;
    default:
        ui->transfer_eventInfo->setText("failed for unknown error. ");
        break;
    }
    g_log.Log(lv_warn, "file transfer error. code:%d", errcode);
}

void FileTransferItem::ChangeTransferingProcess(int percent)
{
    g_log.Log(lv_debug, "file transfer percent :%d", percent);
    if(percent < 0)
        percent = 0;
    if(percent > 100)
        percent = 100;
    emit transferProcessChanged(percent);
}

void FileTransferItem::ChangeTransferEvent(int event)
{
    switch(event)
    {
    case FILE_EVENT_CODE_FINISH:
    case FILE_EVENT_CODE_FINISH_CATHE_HAVE:
    {
        emit transferProcessChanged(100);
        ui->transfer_eventInfo->setText("finished.");
        m_session_valid = false;
        ui->btnSave->setVisible(false);
        ui->btnReject->setVisible(false);
        if(!m_saved_data.issender)
            ui->btnOpen->setVisible(true);
        emit newactivity();
    }
    break;
    case FILE_EVENT_CODE_ACCEPT:
    {
        ui->transfer_eventInfo->setText("the user accepted.");
        ui->btnSave->setVisible(false);
        ui->btnReject->setVisible(false);
    }
    break;
    case FILE_EVENT_CODE_CONNECT:
    {
        ui->transfer_eventInfo->setText("Transferring...");
        ui->btnSave->setVisible(false);
        ui->btnReject->setVisible(false);
    }
    break;
    case FILE_EVENT_CODE_REJECT:
    case FILE_EVENT_CODE_CONFIG_REFUSE:
    case FILE_EVENT_CODE_CONFIG_REFUSE_UNSAFE:
    case FILE_EVENT_CODE_CONFIG_REFUSE_ALL:
    {
        ui->transfer_eventInfo->setText("rejected by user");
        m_session_valid = false;
        ui->btnSave->setVisible(false);
        ui->btnReject->setVisible(false);
        emit newactivity();
    }
    break;
    case FILE_EVENT_CODE_CANCEL:
    {
        ui->transfer_eventInfo->setText("cancelled by user.");
        m_session_valid = false;
        ui->btnSave->setVisible(false);
        ui->btnReject->setVisible(false);
        emit newactivity();
    }
    break;
    case FILE_EVENT_CODE_UNKOWN_ERR:
    {
        ui->transfer_eventInfo->setText("error happened.");
        m_session_valid = false;
        ui->btnSave->setVisible(false);
        ui->btnReject->setVisible(false);
        emit newactivity();
    }
    break;
    default:
        break;
    }
    g_log.Log(lv_debug, "got the reportevent:%d in receiver.", event);
}

void FileTransferItem::OnSaveFile()
{
    // promot a save as dialog
    QString savedpath = QFileDialog::getSaveFileName(this, "save file", QString::fromStdString(utility::GetModulePath() + "/" + m_saved_data.filename));
    if(savedpath.size() < 1)
        return;
    m_saved_data.notifytype = "accept";
    m_saved_data.recvpath = savedpath.toStdString();
    emit notifyOtherSide(m_saved_data);
    ui->transfer_eventInfo->setText("connecting...");
    ui->btnSave->setVisible(false);
    ui->btnReject->setVisible(false);
}

void FileTransferItem::OnCancel()
{

}

void FileTransferItem::OnReject()
{
    m_saved_data.notifytype = "reject";
    emit notifyOtherSide(m_saved_data);
    ui->transfer_eventInfo->setText("rejected by you.");
    m_session_valid = false;
    ui->btnSave->setVisible(false);
    ui->btnReject->setVisible(false);
}

void FileTransferItem::OnRetry()
{

}

void FileTransferItem::on_btnOpen_clicked()
{
    QDesktopServices::openUrl(QUrl("file:///" + QString::fromStdString(m_saved_data.recvpath)));
}
